home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
061-070
/
amok63
/
m2ced
/
txt.lha
/
Files.mod
< prev
next >
Wrap
Text File
|
1991-11-13
|
5KB
|
263 lines
(**********************************************************************
:Program. Files.mod
:Contents. Filebuffer
:Author. Steffen Reith
:Address. Hessenstr. 64, D-8700 Wuerzburg
:Phone. None
:Copyright. Shareware
:Language. Modula-2
:Translator. M2Amiga A+L V3.32d
:History. V1.0 7.Nov 1990
:Bugs. Die Schreibmöglichkeiten dieses Modules sind nicht
ausgetestet ==> EXTREME VORSICHT !!!!!
**********************************************************************)
(*$ StackParms:=FALSE Volatile:=FALSE CaseChk:=FALSE *)
(*$ StackChk:=FALSE RangeChk:=FALSE OverflowChk:=FALSE NilChk:=FALSE *)
IMPLEMENTATION MODULE Files;
FROM Heap IMPORT Allocate,Deallocate;
FROM SYSTEM IMPORT ADR,ADDRESS,CAST;
IMPORT DosD;
IMPORT DosL;
CONST BuffSize=02000H; (* 8k Buffer *)
TYPE FileDesBody=RECORD
DosFile:DosD.FileHandlePtr;
DosSize:LONGINT;
DosPos:LONGINT;
DosMode:FileModes;
BufferPos:INTEGER; (* Buffer nicht grösser als 32 k *)
Buffer:ARRAY[0..BuffSize-1] OF CHAR;
END;
FileDes=POINTER TO FileDesBody;
PROCEDURE FillBuffer(File:FileDes);
VAR Dummy:LONGINT;
BEGIN
File^.BufferPos:=0;
Dummy:=DosL.Read(File^.DosFile,ADR(File^.Buffer),BuffSize);
File^.DosPos:=DosL.Seek(File^.DosFile,0,DosD.current)-Dummy
(* Mit diesem Trick scheint der Positionszeiger immer am Anfang zu stehen. *)
(* d.h. an der physikalischen Adresse, wo der Buffer beginnt. *)
END FillBuffer;
PROCEDURE Flush(File:FileDes);
VAR Dummy:LONGINT;
BEGIN
Dummy:=DosL.Write(File^.DosFile,ADR(File^.Buffer),File^.BufferPos);
File^.BufferPos:=0;
File^.DosPos:=DosL.Seek(File^.DosFile,0,DosD.current)
END Flush;
PROCEDURE FileLength(VAR Name:ARRAY OF CHAR):LONGINT;
VAR IPtr:DosD.FileInfoBlockPtr;
LPtr:DosD.FileLockPtr;
Size:LONGINT;
BEGIN
Allocate(IPtr,SIZE(DosD.FileInfoBlock));
IF IPtr=NIL THEN
RETURN 0
END;
LPtr:=DosL.Lock(ADR(Name),SIZE(DosD.accessRead));
IF LPtr=NIL THEN RETURN 0 END;
IF NOT(DosL.Examine(LPtr,IPtr)) THEN
RETURN 0
END;
Size:=IPtr^.size;
DosL.UnLock(LPtr);
Deallocate(IPtr);
RETURN Size
END FileLength;
PROCEDURE Open (VAR Name:ARRAY OF CHAR;Modus:FileModes):FileDes;
VAR File:FileDes;
Mode:INTEGER;
Dummy:LONGINT;
BEGIN
Allocate(File,SIZE(FileDesBody));
IF File=NIL THEN
IOErr:=NoMem;
RETURN File
END;
IF Modus=read THEN
Mode:=DosD.oldFile
ELSE
Mode:=DosD.newFile
END;
File^.DosMode:=Modus;
File^.DosFile:=DosL.Open(ADR(Name),Mode);
IF File^.DosFile=NIL THEN
Deallocate(File);
IOErr:=NoDosOpen;
RETURN NIL
END;
File^.DosSize:=FileLength(Name);
Dummy:=DosL.Seek(File^.DosFile,0,DosD.beginning);
File^.BufferPos:=0;
IF Modus=read THEN
FillBuffer(File);
END;
RETURN File
END Open;
PROCEDURE Close(File:FileDes);
BEGIN
IF File^.DosMode=write THEN Flush(File) END;
DosL.Close(File^.DosFile);
Deallocate(File)
END Close;
PROCEDURE Read (File:FileDes;BuPtr:ADDRESS;Size:LONGINT);
BEGIN
LOOP
WHILE (Size>0) AND (File^.BufferPos<BuffSize) DO
BuPtr^:=File^.Buffer[File^.BufferPos];
INC(File^.BufferPos);
INC(BuPtr);
DEC(Size);
END;
IF Size=0 THEN RETURN END;
FillBuffer(File)
END
END Read;
PROCEDURE Write (File:FileDes;BuPtr:ADDRESS;Size:LONGINT);
VAR Dummy:LONGINT;
BEGIN
LOOP
WHILE (Size>0) AND (File^.BufferPos<BuffSize) DO
File^.Buffer[File^.BufferPos]:=CAST(CHAR,BuPtr^);
INC(File^.BufferPos);
INC(BuPtr);
DEC(Size);
END;
IF Size=0 THEN RETURN END;
Flush(File)
END
END Write;
PROCEDURE Read1 (File:FileDes):CHAR;
VAR ch:CHAR;
BEGIN
IF (File^.BufferPos>=BuffSize-1) THEN
FillBuffer(File)
END;
ch:=File^.Buffer[File^.BufferPos];
INC(File^.BufferPos);
RETURN (ch);
END Read1;
PROCEDURE Write1 (File:FileDes;ch:CHAR);
BEGIN
IF (File^.BufferPos<=BuffSize-1) THEN
File^.Buffer[File^.BufferPos]:=ch
END;
INC(File^.BufferPos);
IF File^.BufferPos=BuffSize THEN
Flush(File)
END
END Write1;
PROCEDURE Seek (File:FileDes;Pos:LONGINT;Loc:LocModes);
VAR Off:LONGINT;
PROCEDURE CheckBounds(VAR Pos:LONGINT):BOOLEAN;
BEGIN
IF (Pos>=0) AND (Pos<BuffSize) THEN
RETURN TRUE
ELSE
RETURN FALSE
END
END CheckBounds;
PROCEDURE SetPtr(File:FileDes;Pos:LONGINT;Loc:LocModes);
VAR Dummy:LONGINT;
BEGIN
CASE Loc OF
|Front:Dummy:=DosL.Seek(File^.DosFile,Pos,DosD.beginning);
|Current:Dummy:=DosL.Seek(File^.DosFile,Pos,DosD.current);
|End:Dummy:=DosL.Seek(File^.DosFile,Pos,DosD.end);
END
END SetPtr;
PROCEDURE Update(File:FileDes;Pos:LONGINT;Loc:LocModes);
BEGIN
IF File^.DosMode=read THEN
SetPtr(File,Pos,Loc);
FillBuffer(File)
ELSE
Flush(File);
SetPtr(File,Pos,Loc)
END
END Update;
BEGIN
CASE Loc OF
|Front:
Off:=Pos-File^.DosPos;
IF CheckBounds(Off) THEN
File^.BufferPos:=Off;
ELSE
Update(File,Pos,Loc)
END;
|Current:
Off:=File^.BufferPos+Pos;
IF CheckBounds(Off) THEN
File^.BufferPos:=Off;
ELSE
Update(File,Pos,Loc)
END;
|End:
Off:=(File^.DosSize-1)+Pos-File^.DosPos;
(* Diese Aktion macht bei write keinen Sinn Achtung Bug und Absturz *)
IF CheckBounds(Off) THEN
File^.BufferPos:=Off;
ELSE
Update(File,Pos,Loc)
END
END
END Seek;
PROCEDURE WhereIAm(File:FileDes):LONGINT;
BEGIN
RETURN File^.DosPos+File^.BufferPos
END WhereIAm;
BEGIN
END Files.